package net.yla.smartbus.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import net.yla.smartbus.core.validation.DtoName;
import net.yla.smartbus.core.validation.GetDtoName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yanglei
 * @date 2020/8/20
 * @description 实现DO层因为字段不同用大量的get/set方法
 * @method 返回JSONObject对象
 */
@Slf4j
public class DtoUtils {

    private static JSONArray jArray = new JSONArray();

    private static JSONObject jsonObject;

//  private static final Logger logger = LoggerFactory.getLogger(DtoUtils.class);

    /**
     * 返回类上的字段@DtoName中group的值不为空的JSONObject对象
     *
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static JSONObject asDtoJsonForGroup(Object object, String group) {
        //获取类上@GetDtoName的注解
        Annotation annotation = object.getClass().getAnnotation(GetDtoName.class);
        if (annotation != null) {
            Map<String, Object> map = new HashMap<>();
            //获取字段
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                //如果字段是private的,不加这个会抛异常
                field.setAccessible(true);
                if (field.isAnnotationPresent(DtoName.class)) {
                    DtoName dtoName = field.getAnnotation(DtoName.class);
                    //获取group的值 判断是否包含
                    if (Arrays.asList(dtoName.group()).contains(group)) {
                        try {
                            //注解内的值value
                            map.put(dtoName.value(), field.get(object));
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            //不加SerializerFeature.WriteMapNullValue如果map的value为null json是没有该数据的  WriteDateUseDateFormat格式化json日前
            jsonObject = JSON.parseObject(jArray.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat));
            return jsonObject;
        } else {
            log.info("can not find @GetDtoName annotation...");
            return null;
        }
    }

    /**
     * 加载所有字段且字段上未标注group
     *
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static JSONObject asDtoJsonForAll(Object object) {
        Annotation annotation = object.getClass().getAnnotation(GetDtoName.class);
        if (annotation != null) {
            Map<String, Object> map = new HashMap<>();
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                try {
                    if (field.isAnnotationPresent(DtoName.class)) {
                        DtoName dtoName = field.getAnnotation(DtoName.class);
                        map.put(dtoName.value(), field.get(object));
                    } else {
                        map.put(field.getName(), field.get(object));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            jsonObject = JSON.parseObject(jArray.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat));
            return jsonObject;
        } else {
            log.info("can not find @GetDtoName annotation...");
            return null;
        }
    }

    /**
     * 加载只有@GetDtoName注解没有group的字段
     *
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static JSONObject asDtoJsonForOnly(Object object) {
        Annotation annotation = object.getClass().getAnnotation(GetDtoName.class);
        if (annotation != null) {
            Map<String, Object> map = new HashMap<>();
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(DtoName.class)) {
                    DtoName dtoName = field.getAnnotation(DtoName.class);
                    try {
                        if (dtoName.value().equals("")) {
                            map.put(field.getName(), field.get(object));
                        } else {
                            map.put(dtoName.value(), field.get(object));
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            jsonObject = JSON.parseObject(jArray.toJSONString(map, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat));
            return jsonObject;
        } else {
            log.info("can not find @GetDtoName annotation...");
            return null;
        }
    }
}
